---
title: MCP Sampling AI Provider
description: Learn how to use the MCP Sampling AI Provider.
---

# MCP Sampling AI Provider

The [MCP Sampling AI Provider](https://github.com/mcpc-tech/mcpc/tree/main/packages/mcp-sampling-ai-provider) allows MCP servers to use AI models through the AI SDK by leveraging your existing client subscriptions (like VS Code Copilot). This transforms your MCP server into an agentic tool that can reason and make decisions, without requiring separate API keys or subscriptions.

The provider implements `LanguageModelV2` by forwarding requests through MCP's [sampling feature](https://modelcontextprotocol.io/specification/2025-06-18/client/sampling) to the MCP client, offering unique advantages:

- **Server-Side AI Integration**: Enable MCP servers to call language models directly through AI SDK's standard interface
- **No Direct Model Management**: Forward AI requests to MCP clients, eliminating the need for multiple API keys
- **Model Flexibility**: Let MCP clients decide which model to use based on preferences (cost, speed, intelligence)
- **Seamless AI SDK Compatibility**: Support for `generateText`, `streamText`, `generateObject`, and experimental tool calling
- **Client Sampling Support**: Add sampling capability to any MCP client with built-in helpers
- **Agentic Tools**: Transform simple MCP tools into intelligent agents that can reason and make decisions

Learn more about MCP Sampling in the [MCP Specification](https://modelcontextprotocol.io/specification/2025-06-18/client/sampling).

## Prerequisites

**Warning:** This provider has specific requirements:

1. **Must run inside an MCP Server** - This is not a standalone AI SDK provider. It works by forwarding requests to the MCP client.
2. **Client must support MCP Sampling** - The connected MCP client must implement the sampling capability, or you can implement it yourself (see [Client Sampling](#client-sampling-for-clients-without-native-support) below).

### Clients with Sampling Support

- VS Code (with GitHub Copilot) - Supported
- Claude Desktop - Tracking ([Issue #1785](https://github.com/anthropics/claude-code/issues/1785))
- Cursor - Tracking ([Issue #3023](https://github.com/cursor/cursor/issues/3023))

See the [full list of MCP clients](https://modelcontextprotocol.io/clients) for more options.

**Alternative:** Use `setupClientSampling()` to add sampling to any MCP client (see example below).

## Setup

The MCP Sampling AI Provider is available in the `@mcpc-tech/mcp-sampling-ai-provider` module. You can install it with:

<Tabs items={['pnpm', 'npm', 'yarn', 'bun', 'deno']}>
  <Tab>
    <Snippet text="pnpm add @mcpc-tech/mcp-sampling-ai-provider" dark />
  </Tab>
  <Tab>
    <Snippet text="npm install @mcpc-tech/mcp-sampling-ai-provider" dark />
  </Tab>
  <Tab>
    <Snippet text="yarn add @mcpc-tech/mcp-sampling-ai-provider" dark />
  </Tab>
  <Tab>
    <Snippet text="bun add @mcpc-tech/mcp-sampling-ai-provider" dark />
  </Tab>
  <Tab>
    <Snippet text="deno add jsr:@mcpc/mcp-sampling-ai-provider" dark />
  </Tab>
</Tabs>

## Provider Instance

To create an MCP Sampling provider instance, use the `createMCPSamplingProvider` function with your MCP server instance:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';

// Create an MCP server with sampling capability
const server = new Server(
  { name: 'my-agent', version: '1.0.0' },
  { capabilities: { sampling: {}, tools: {} } },
);

const provider = createMCPSamplingProvider({ server });
```

### Configuration

The provider accepts the following configuration:

- **server** _MCP Server instance_

  An MCP Server instance that has sampling capability enabled.

## Language Models

Create a language model instance using the `languageModel()` method:

```typescript
const model = provider.languageModel({
  modelPreferences: {
    hints: [{ name: 'gpt-5-mini' }],
    costPriority: 0.5,
    speedPriority: 0.8,
    intelligencePriority: 0.9,
  },
});
```

### Model Preferences

The `languageModel()` method accepts optional model preferences:

- **hints** _Array\<\{ name: string \}\>_

  Array of model name hints (e.g., `[{ name: "gpt-5-mini" }]`). These suggest preferred models to the MCP client.

- **costPriority** _number (0-1)_

  Higher values prefer cheaper models. Default is 0.

- **speedPriority** _number (0-1)_

  Higher values prefer faster models. Default is 0.

- **intelligencePriority** _number (0-1)_

  Higher values prefer more capable models. Default is 0.

See [MCP Model Preferences](https://modelcontextprotocol.io/specification/2025-06-18/client/sampling#model-preferences) for more details.

## Examples

### `generateText`

Generate text using the MCP Sampling Provider in an MCP server tool:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';

// Create MCP server with sampling capability
const server = new Server(
  { name: 'translator', version: '1.0.0' },
  { capabilities: { sampling: {}, tools: {} } },
);

// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'translate',
        description: 'Translate text to a target language using AI',
        inputSchema: {
          type: 'object',
          properties: {
            text: {
              type: 'string',
              description: 'The text to translate',
            },
            target_lang: {
              type: 'string',
              description: 'The target language (e.g., "Spanish", "French")',
            },
          },
          required: ['text', 'target_lang'],
        },
      },
    ],
  };
});

// Register a translation tool that uses AI
server.setRequestHandler(CallToolRequestSchema, async request => {
  if (request.params.name === 'translate') {
    // Create provider from the server
    const provider = createMCPSamplingProvider({ server });

    // Use AI SDK to translate text
    const { text } = await generateText({
      model: provider.languageModel({
        modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
      }),
      prompt: `Translate to ${request.params.arguments?.target_lang}: ${request.params.arguments?.text}`,
    });

    return { content: [{ type: 'text', text }] };
  }
});

// Connect and start
const transport = new StdioServerTransport();
await server.connect(transport);
```

### `streamText`

Stream text responses using the MCP Sampling Provider:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { streamText } from 'ai';

const server = new Server(
  { name: 'ai-assistant', version: '1.0.0' },
  { capabilities: { sampling: {}, tools: {} } },
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'generate-story',
        description: 'Generate a story or poem using AI',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
    ],
  };
});

server.setRequestHandler(CallToolRequestSchema, async request => {
  if (request.params.name === 'generate-story') {
    const provider = createMCPSamplingProvider({ server });

    const result = streamText({
      model: provider.languageModel({
        modelPreferences: {
          hints: [{ name: 'gpt-5-mini' }],
          speedPriority: 0.9,
        },
      }),
      prompt: 'Write a short poem about coding.',
    });

    const text = await result.text;

    return { content: [{ type: 'text', text }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
```

### `generateObject`

Generate structured objects using the MCP Sampling Provider:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateObject } from 'ai';
import { z } from 'zod';

const server = new Server(
  { name: 'recipe-generator', version: '1.0.0' },
  { capabilities: { sampling: {}, tools: {} } },
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'generate-recipe',
        description: 'Generate a recipe using AI',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
    ],
  };
});

server.setRequestHandler(CallToolRequestSchema, async request => {
  if (request.params.name === 'generate-recipe') {
    const provider = createMCPSamplingProvider({ server });

    const recipeSchema = z.object({
      recipe: z.object({
        name: z.string(),
        cuisine: z.string(),
        ingredients: z.array(z.string()),
        steps: z.array(z.string()),
      }),
    });

    const { object } = await generateObject({
      mode: 'json',
      model: provider.languageModel({
        modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
      }),
      schema: recipeSchema,
      prompt: 'Generate a delicious lasagna recipe.',
    });

    return {
      content: [{ type: 'text', text: JSON.stringify(object, null, 2) }],
    };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
```

### Tool Calling (Experimental)

Use tools with the MCP Sampling Provider. Note: This is implemented via system prompt and may not be as reliable as native tool support:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { createMCPSamplingProvider } from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';
import { z } from 'zod';

const server = new Server(
  { name: 'weather-agent', version: '1.0.0' },
  { capabilities: { sampling: {}, tools: {} } },
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'ask-weather',
        description: 'Ask a weather-related question',
        inputSchema: {
          type: 'object',
          properties: {
            question: {
              type: 'string',
              description: 'The weather question to ask',
            },
          },
        },
      },
    ],
  };
});

server.setRequestHandler(CallToolRequestSchema, async request => {
  if (request.params.name === 'ask-weather') {
    const provider = createMCPSamplingProvider({ server });

    const result = await generateText({
      model: provider.languageModel({
        modelPreferences: { hints: [{ name: 'gpt-5-mini' }] },
      }),
      tools: {
        getWeather: {
          description: 'Get the weather for a location',
          parameters: z.object({
            city: z.string().describe('The city name'),
          }),
          execute: async ({ city }) => {
            return `The weather in ${city} is sunny and 72°F`;
          },
        },
      },
      prompt:
        request.params.arguments?.question ||
        'What is the weather in San Francisco?',
      maxSteps: 5,
    });

    return { content: [{ type: 'text', text: result.text }] };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
```

### Additional Examples

See the [examples directory](https://github.com/mcpc-tech/mcpc/tree/main/packages/mcp-sampling-ai-provider/examples) for more complete working examples:

- [generate_text_example.ts](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples/generate_text_example.ts) - Basic text generation
- [stream_text_example.ts](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples/stream_text_example.ts) - Streaming responses
- [generate_object_example.ts](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples/generate_object_example.ts) - Structured output
- [client-sampling-example.ts](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples/client-sampling-example.ts) - Client sampling implementation

## Client Sampling (for clients without native support)

If your MCP client doesn't support sampling natively, you can add sampling capability using `setupClientSampling` with model preferences:

```typescript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import {
  convertAISDKFinishReasonToMCP,
  selectModelFromPreferences,
  setupClientSampling,
} from '@mcpc-tech/mcp-sampling-ai-provider';
import { generateText } from 'ai';

const client = new Client(
  { name: 'my-client', version: '1.0.0' },
  { capabilities: { sampling: {} } },
);

setupClientSampling(client, {
  handler: async params => {
    const modelId = selectModelFromPreferences(params.modelPreferences, {
      hints: {
        'gpt-5': 'openai/gpt-5-mini',
        'gpt-mini': 'openai/gpt-5-mini',
      },
      priorities: {
        speed: 'openai/gpt-5-mini',
        intelligence: 'openai/gpt-5-mini',
      },
      default: 'openai/gpt-5-mini',
    });

    const result = await generateText({
      model: modelId,
      messages: params.messages,
    });

    return {
      model: modelId,
      role: 'assistant',
      content: { type: 'text', text: result.text },
      stopReason: convertAISDKFinishReasonToMCP(result.finishReason),
    };
  },
});

const transport = new StdioClientTransport({
  command: 'npx',
  args: ['-y', 'example_mcp_server.ts'],
});

await client.connect(transport);
```

See the [complete example](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples/client-sampling-example.ts) for more details.

## How It Works

The request flow is straightforward:

1. AI SDK calls the language model
2. Provider converts to MCP `sampling/createMessage` format
3. MCP client handles the sampling request
4. Provider converts response back to AI SDK format

The MCP client (e.g., VS Code, Claude Desktop) decides which actual model to use based on the provided `modelPreferences`.

## Limitations

- **No token counting**: MCP doesn't provide token usage information (returns 0)
- **No native streaming**: MCP sampling doesn't support streaming - the provider calls `doGenerate` first, then emits the complete response as stream events
- **Experimental tool/JSON support**: Implemented via systemPrompt as MCP sampling doesn't natively support these features

## Additional Resources

- [MCP Sampling AI Provider Repository](https://github.com/mcpc-tech/mcpc/tree/main/packages/mcp-sampling-ai-provider)
- [NPM Package](https://www.npmjs.com/package/@mcpc-tech/mcp-sampling-ai-provider)
- [JSR Package](https://jsr.io/@mcpc/mcp-sampling-ai-provider)
- [MCP Specification](https://modelcontextprotocol.io/)
- [Example Code](https://github.com/mcpc-tech/mcpc/blob/main/packages/mcp-sampling-ai-provider/examples)
